package com.spring.sd.ignore;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * {@code @Autowired} 是等同于set注入的，比如 <br/>
 * {@code
 *
 * @Autowired <br/>
 * private B b;<br/>
 * }
 * 等同于<br/>
 * {@code
 * private B b; <br/>
 * public B getB() {<br/>
 * return b;<br/>
 * }<br/>
 * }<br/>
 * 如果不忽略一堆Aware接口beanFactory.ignoreDependencyInterface(XXAware.class);
 * 那么在属性填充阶段，比如按类型/按名称自动装配的时候就会赋值。那么spring框架本身在属性填充之后
 * 又会执行Aware接口，会导致接口调用两次，并且Aware接口提前执行了也会导致spring容器的一些属性
 * 无法控制管理，并且也脱离了bean的声明周期管理
 */
public class A implements SmartInitializingSingleton, InterfaceTest, InitializingBean, ApplicationContextAware, BeanNameAware, BeanFactoryAware, EnvironmentAware, DisposableBean {

    //@Autowired
    private B b;

    private C c;

    @Override
    public void setC(C c) {
        this.c = c;
        System.out.println(">>>>>> 1 填充C属性");
    }

    //public B getB() {
    //    return b;
    //}

    @Override
    public void afterPropertiesSet() throws Exception {
        // 同样可以在这里修改bean的属性值
        System.out.println(">>>>>> 9 InitialingBean 完整的bean之后执行的方法");
    }

    @PostConstruct
    public void init() {
        System.out.println(">>>>>> 8 A的初始化方法 @PostConstruct");
    }


    public void initMe() {
        System.out.println(">>>>>> 10 init-method");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(">>>>>> 5 执行ApplicationContextAware，注入 ApplicationContext");
    }

    public void setB(B b) {
        this.b = b;
        System.out.println(">>>>>> 1 填充B属性");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        // 同样可以在这里修改bean的属性值
        System.out.println(">>>>>> 3 执行BeanFactoryAware");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println(">>>>>> 2 执行BeanNameAware");

    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println(">>>>>> 4 执行EnvironmentAware");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println(">>>>>> 销毁3 DisposableBean");
    }

    @PreDestroy
    public void destroy1() {
        System.out.println(">>>>>> 销毁2 @PreDestroy");
    }


    public void destroyMe() {
        System.out.println(">>>>>> 销毁4 destroy-method");
    }

    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("初始化全部完成 调用SmartInitializingSingleton >>>>>>>>>>>> ");
    }

    //public C getC() {
    //    return c;
    //}
}
